﻿using BnbjoyBackend.Site.ConstantsNS;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Script.Serialization;
using System.Web.Security;

namespace BnbjoyBackend.Site.Security
{
    public class BnbjoyAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure
            filterContext.Result = new RedirectResult("~/Account/Rejected");
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            //var rd = httpContext.Request.RequestContext.RouteData;
            //string currentAction = rd.GetRequiredString("action");
            //string currentController = rd.GetRequiredString("controller");

            return true;
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //本来验证应该做在AuthorizeCore，但考虑到这里跳转有两个可能，一个到login，一个到rejected，所以放在此处

            if (this.AuthorizeCore(filterContext.HttpContext))
            {
                base.OnAuthorization(filterContext);

                var actionName = filterContext.ActionDescriptor.ActionName;
                var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

                //判断用户是否已登录
                if (!AuthorizedUserManager.Instance.UserLoggedIn)
                {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Login" }
                                           });

                    //加入EmptyResult就告诉ASP.NET MVC在本拦截器执行结束后，不必再为当前请求执行Controller中Action的代码
                    //filterContext.Result = new EmptyResult(); 
                    return;
                }
                else
                {
                    //获取该用户拥有管理权限的bnb列表
                    dynamic inManagedBnbsRes = AuthorizedUserManager.Instance.GetCurrentBnbInfoSync();
                    List<dynamic> inManagedBnbs = null;
                    if (inManagedBnbsRes == null || (Common.IsPropertyExist(inManagedBnbsRes, "StatusCode") && inManagedBnbsRes.StatusCode == HttpStatusCode.Redirect))
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Rejected" }
                                           });

                        return;
                    }
                    else 
                    {
                        inManagedBnbs = Enumerable.ToList<dynamic>(inManagedBnbsRes);
                    }

                    if (HttpContext.Current.Session[Constants.OnSelectBnbSession] == null)
                        HttpContext.Current.Session[Constants.OnSelectBnbSession] = inManagedBnbs.FirstOrDefault();

                    var param = HttpContext.Current.Session[Constants.OnSelectBnbSession] as dynamic;
                    dynamic userInfoRes = AuthorizedUserManager.Instance.GetUserInfoSync((string)param.UserId, (string)param.RoleName, (string)param.BnbId);
                    if (userInfoRes == null || (Common.IsPropertyExist(userInfoRes, "StatusCode") && userInfoRes.StatusCode == HttpStatusCode.Redirect))
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Rejected" }
                                           });

                        return;
                    }

                    if (inManagedBnbsRes == null || (Common.IsPropertyExist(inManagedBnbsRes, "StatusCode") && inManagedBnbsRes.StatusCode == HttpStatusCode.Redirect))
                    {
                        //如果没有任何可以管理的bnb，或者获取异常
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Rejected" }
                                           });

                        return;
                    }

                    //得到当前用户权限列表
                    var jss = new JavaScriptSerializer();
                    var permissionDic = jss.Deserialize<Dictionary<string, string>>(Convert.ToString(userInfoRes.AuthMap));
                    if (permissionDic != null && permissionDic.Count > 0)
                    {
                        //如果权限列表有权限，那么判断用户是否有查看本页的权限
                        if (!AccessActionPermission(actionName, controllerName, permissionDic))
                        {
                            //如果没有相应的权限，那么拒绝
                            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Rejected" }
                                           });

                            return;
                        }
                    }
                    else
                    {
                        //如果权限列表一个权限都没有，直接拒绝
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary{
                                            { "Controller", "Account" },
                                            { "Action", "Rejected" }
                                           });

                        return;
                    }
                }
            }
            else
            {
                this.HandleUnauthorizedRequest(filterContext);
            }

        }


        private bool AccessActionPermission(string actionName, string controllerName, Dictionary<string, string> permissionDic)
        {
            bool result = false;
            string currentPage = (controllerName + "/" + actionName).ToLower(); //如：Home/Index
            string currentPageRule = (controllerName + "/*").ToLower();  //通配，如：Home/*

            //得到当前用户的权限列表
            foreach (var kvp in permissionDic)
            {
                var urlValue = kvp.Value.ToLower();
                result = urlValue == currentPage || urlValue == currentPageRule || currentPage.Contains("account");
                if (result)
                    break;
            }

            return result;
        }
    }
}